package com.cap.bts.framework.auth.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.cap.bts.framework.auth.constant.AuthConstant;
import com.cap.bts.framework.common.constant.WebServiceRegisterConstant;

import org.apache.log4j.Logger;

import com.cap.bts.framework.common.dto.UserSession;
import com.cap.bts.framework.common.util.CookieUtils;
import com.cap.bts.framework.common.util.TokenUtils;
import com.cap.bts.framework.common.util.Utils;
import com.cap.bts.framework.common.util.WSRegPropertiesUtil;

public final class UserAuthenticationUtils {
	
	private static final Logger logger = Logger.getLogger(UserAuthenticationUtils.class);

    private final static String cipherKey = "dms_0987654321";

    private static int EXPIRY = 1800; // 60 * 30 = 30 minutes
    
    private static Map<String, UserSession> sessionMap = new HashMap<String,UserSession>();
		
	//private static List<String> needForceLogoutIPList = new ArrayList<String>();
    
    private static List<String> needForceLogoutSessionIds = new ArrayList<String>();
    
    private UserAuthenticationUtils(){}

    public static boolean isTrustedUser(HttpServletRequest req, HttpServletResponse res) {
        String user = CookieUtils.getCookie(req, res, AuthConstant.COOKIE_USER_KEY);
        if (user != null && user.length() > 0) {
            String encryption = CookieUtils.getCookie(req, res, AuthConstant.COOKIE_CODE_KEY);
            if (encryption != null && encryption.length() > 0)
                return TokenUtils.verifyEncryptionToken(user, encryption);
            else
                return false;
        } else
            return false;
    }

    public static String getLoginUserId(HttpServletRequest req, HttpServletResponse res) {
        if (isTrustedUser(req, res)) {
            String user = CookieUtils.getCookie(req, res, AuthConstant.COOKIE_USER_KEY);

            return user;
        }
        return null;
    }
    
    public static String getCanExportValue(HttpServletRequest req, HttpServletResponse res) {
        if (isTrustedUser(req, res)) {
            String canExport = CookieUtils.getCookie(req, res, AuthConstant.COOKIE_CAN_EXPORT_KEY);

            return canExport;
        }
        return null;
    }
    
    public static void setLoginToCookie(HttpServletRequest req, HttpServletResponse res, String user){
        setLoginToCookie(req, res, user, EXPIRY);
    }
    
    
    public static void setLoginToCookie(HttpServletRequest req, HttpServletResponse res, String user, int expiry) {
        String domain = PropertiesUtil.getProperties(AuthConstant.DMS_DOMAIN_KEY);
        CookieUtils.setCookie(req, res, domain, AuthConstant.COOKIE_USER_KEY, user, expiry);
        CookieUtils.setCookie(req, res, domain, AuthConstant.COOKIE_CODE_KEY, TokenUtils
            .getEncryptionToken(user), expiry);
    }
    
    public static void setSessionIdToCookie(HttpServletRequest req, HttpServletResponse res) {
        String domain = PropertiesUtil.getProperties(AuthConstant.DMS_DOMAIN_KEY);
        CookieUtils.setCookie(req, res, domain, AuthConstant.COOKIE_IDENTIFY_SESSION_ID, req.getSession().getId(), EXPIRY);
    }
    
    public static String getSessionIdFromCookie(HttpServletRequest req, HttpServletResponse res) {
    	
    	String sessionId = CookieUtils.getCookie(req, res, AuthConstant.COOKIE_IDENTIFY_SESSION_ID);
    	return sessionId;
    }
    
    public static void setCookie(HttpServletRequest req, HttpServletResponse res, String canExport) {
        String domain = PropertiesUtil.getProperties(AuthConstant.DMS_DOMAIN_KEY);
        CookieUtils.setCookie(req, res, domain, AuthConstant.COOKIE_CAN_EXPORT_KEY, canExport, EXPIRY);
    }
    
    public static void setLogout(HttpServletRequest req, HttpServletResponse res, String user) {
        /*String domain = PropertiesUtil.getProperties(AuthConstant.DMS_DOMAIN_KEY);
        CookieUtils.setCookie(req, res, domain, AuthConstant.COOKIE_USER_KEY, "abandon", 0);
        CookieUtils.setCookie(req, res, domain, AuthConstant.COOKIE_CODE_KEY, "abandon", 0);*/
        //invalid session
        req.getSession().invalidate();
        /*removeSessionByUserName(user);
        resetForceLogoutFlag(req,res);*/
        
    }

    /**
     * this method set value from propertie file
     * 
     */
    public static void initProValue() {
        EXPIRY = Integer.valueOf(PropertiesUtil.getProperties(AuthConstant.COOKIE_EXPIRY_TIME_KEY));
    }
    
    public static boolean isResetPasswordRequest(HttpServletRequest req){
        if(req.getRequestURI().equals(req.getContextPath() + "/ge/dealer/resetpasswd/resetPassword")){
            return true;
        }
        return false;
    }
    
    public static void checkDiffUserInOneSession(HttpServletRequest request, String userName){
    	String currentSessionId = request.getSession().getId();
    	if(!sessionMap.containsKey(userName)){
    		for(UserSession userSession: sessionMap.values()){
    			if(userSession != null && currentSessionId.equals(userSession.getSessionId())){
    				try {
						userSession.getSession().invalidate();
					} catch (Exception e) {
						logger.error("Session already invalid.");
					}
    			}
    		}
    	}
    	
    }
    
    
    /**
	 * Check whether the same user has login, then force expire the previous user session
	 * @Date        :      Mar 7, 2012
	 * @param request
	 * @param userName
	 */
	public static void checkLoginUserSession(HttpServletRequest request,String userName){
		
		//resetForceLogoutFlag(request);
		
		//String userHost = request.getRemoteHost();
		String sessionId = request.getSession().getId();
		UserSession userSession = new UserSession();
		//userSession.setRequestClientAddress(userHost);
		userSession.setSessionId(sessionId);
		userSession.setSession(request.getSession());
		//Handle the same user login in different session client		
		if(sessionMap.containsKey(userName)){
			UserSession existUserSession = sessionMap.get(userName);
			if(existUserSession != null && Utils.notEmpty(existUserSession.getSessionId())){
				try {
					if(!existUserSession.getSessionId().equals(sessionId)){
						existUserSession.getSession().invalidate();
						//Call dms Web Service To Notify dms Session has expired.
						notifyDmsSessionExpiration(existUserSession.getSessionId());
						//needForceLogoutIPList.add(existUserSession.getRequestClientAddress());
						needForceLogoutSessionIds.add(existUserSession.getSessionId());
					}
				} catch (Exception e) {				
					logger.info("Session already invalidated");
				}
				
			}
			
		}
		sessionMap.put(userName, userSession);
		
	}
	
	public static boolean isForceLogout(HttpServletRequest req, HttpServletResponse res){
		/*String clientIP = request.getRemoteHost();
		if(needForceLogoutIPList != null && needForceLogoutIPList.contains(clientIP)){
			needForceLogoutIPList.remove(clientIP);
			return true;
		}*/
		
		String sessionId = getSessionIdFromCookie(req,res);
		if(needForceLogoutSessionIds != null && needForceLogoutSessionIds.contains(sessionId)){
			needForceLogoutSessionIds.remove(sessionId);
			return true;
		}
		
		return false;
	}
	
	public static void removeSessionByUserName(String userName){
		sessionMap.remove(userName);
	}
	
	public static void resetForceLogoutFlag(HttpServletRequest request,HttpServletResponse response){
		//String clientIP = request.getRemoteHost();
		String sessionId = getSessionIdFromCookie(request,response);
		request.getSession().setAttribute("isForceLogout", false);
		if(needForceLogoutSessionIds != null && needForceLogoutSessionIds.contains(sessionId)){
			needForceLogoutSessionIds.remove(sessionId);
		}
		removeExpirationSessionIdFromGdms(sessionId);
		/*if(needForceLogoutIPList != null && needForceLogoutIPList.contains(clientIP)){
			needForceLogoutIPList.remove(clientIP);
		}*/
		
		
	}
	
	
	private static void notifyDmsSessionExpiration(String sessionId){}
	
	private static void removeExpirationSessionIdFromGdms(String sessionId){}
    

}
